package com.thinvent.smart.chain.contract;

import com.alibaba.fastjson.JSON;
import com.alipay.mychain.sdk.api.MychainClient;
import com.alipay.mychain.sdk.api.env.ClientEnv;
import com.alipay.mychain.sdk.api.env.ISslOption;
import com.alipay.mychain.sdk.api.env.SignerOption;
import com.alipay.mychain.sdk.api.env.SslBytesOption;
import com.alipay.mychain.sdk.api.logging.AbstractLoggerFactory;
import com.alipay.mychain.sdk.api.logging.ILogger;
import com.alipay.mychain.sdk.api.utils.ConfidentialUtil;
import com.alipay.mychain.sdk.api.utils.Utils;
import com.alipay.mychain.sdk.common.VMTypeEnum;
import com.alipay.mychain.sdk.crypto.MyCrypto;
import com.alipay.mychain.sdk.crypto.keyoperator.Pkcs8KeyOperator;
import com.alipay.mychain.sdk.crypto.keypair.Keypair;
import com.alipay.mychain.sdk.crypto.signer.SignerBase;
import com.alipay.mychain.sdk.domain.account.Identity;
import com.alipay.mychain.sdk.domain.transaction.TransactionReceipt;
import com.alipay.mychain.sdk.errorcode.ErrorCode;
import com.alipay.mychain.sdk.message.transaction.AbstractTransactionRequest;
import com.alipay.mychain.sdk.message.transaction.TransactionReceiptResponse;
import com.alipay.mychain.sdk.message.transaction.confidential.ConfidentialRequest;
import com.alipay.mychain.sdk.message.transaction.contract.*;
import com.alipay.mychain.sdk.type.BaseFixedSizeUnsignedInteger;
import com.alipay.mychain.sdk.utils.ByteUtils;
import com.alipay.mychain.sdk.utils.IOUtil;
import com.alipay.mychain.sdk.utils.RandomUtil;
import com.alipay.mychain.sdk.vm.EVMOutput;
import com.alipay.mychain.sdk.vm.EVMParameter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.math.BigInteger;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;

/**
 * <pre>
 *    @author : orange
 *    @e-mail : 495314527@qq.com
 *    @time   : 2022/11/30 16:52
 *    @desc   :
 *    @version: 1.0
 * </pre>
 */
public class AntChainDemo {

    /**
     * contract code
     */
    private static String contractCodeString = "0x608060405234801561001057600080fd5b50610615806100206000396000f300608060405260043610610078576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806307dba6bf1461007d57806320628eb3146100f05780633f08c2bb146101595780636b59084d146101d657806370e7640614610266578063ca3f7d22146102d9575b600080fd5b34801561008957600080fd5b506100ee600480360381019080803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190505050610356565b005b3480156100fc57600080fd5b50610157600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506103d3565b005b34801561016557600080fd5b506101c0600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610447565b6040518082815260200191505060405180910390f35b3480156101e257600080fd5b506101eb6104bb565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561022b578082015181840152602081019050610210565b50505050905090810190601f1680156102585780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561027257600080fd5b506102d7600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001909291905050506104f8565b005b3480156102e557600080fd5b50610340600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610575565b6040518082815260200191505060405180910390f35b806000836040518082805190602001908083835b60208310151561038f578051825260208201915060208101905060208303925061036a565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020600082825401925050819055505050565b60646000826040518082805190602001908083835b60208310151561040d57805182526020820191506020810190506020830392506103e8565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390208190555050565b600080826040518082805190602001908083835b602083101515610480578051825260208201915060208101905060208303925061045b565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020549050919050565b60606040805190810160405280600f81526020017f7465737420737563636573732e2e2e0000000000000000000000000000000000815250905090565b806000836040518082805190602001908083835b602083101515610531578051825260208201915060208101905060208303925061050c565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020600082825403925050819055505050565b600080826040518082805190602001908083835b6020831015156105ae5780518252602082019150602081019050602083039250610589565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390205490509190505600a165627a7a7230582061b570a2f4d0c62a7afbdb57cb7e7c5e43155a0391860a89bf69b061e01714640029";

    private static byte[] contractCode = ByteUtils.hexStringToBytes(contractCodeString);
    /**
     * contract id
     */
    // private static String testContractId = "CreditManager" +
    // System.currentTimeMillis();
    private static String testContractId = "Bank002";

    /**
     * baas上创建的帐户名字
     */
    private static final String account = "yujw1";
    private static Identity userIdentity;
    private static Keypair userKeypair;

    /**
     * create account test
     */
    private static Identity testAccount1 = Utils.getIdentityByName("test_account_" + System.currentTimeMillis());
    /**
     * sdk client
     */
    private static MychainClient sdk;
    /**
     * client key password
     */
    private static String keyPassword = "123456"; // 根据实际情况更新，申请证书时候指定的SSL密码
    /**
     * user password
     */
    private static String userPassword = "123456"; // 根据实际情况更新。申请证书时，创建账户的密码
    /**
     * host ip
     */

    private static String host = "47.111.195.13"; // 根据实际情况更新，在BaaS平台，通过查看目标合约链"详情"，在"区块浏览器"中查看"节点详情"可获取链节点的 IP地址 和 端口号。

    /**
     * server port
     */
    private static int port = 18133; // 根据实际情况更新
    /**
     * trustCa password.
     */
    private static String trustStorePassword = "mychain";
    /**
     * mychain environment
     */
    private static ClientEnv env;
    /**
     * mychain is tee Chain
     */
    private static boolean isTeeChain = false;
    /**
     * tee chain publicKeys
     */
    private static List<byte[]> publicKeys = new ArrayList<byte[]>();
    /**
     * tee chain secretKey
     */
    private static String secretKey = "123456";

    private static final Logger logger = LoggerFactory.getLogger(AntChainDemo.class);

    private static void exit(String tag, String msg) {
        exit(String.format("%s error : %s ", tag, msg));
    }

    private static void exit(String msg) {
        System.out.println(msg);
        System.exit(0);
    }

    private static String getErrorMsg(int errorCode) {
        int minMychainSdkErrorCode = ErrorCode.SDK_INTERNAL_ERROR.getErrorCode();
        if (errorCode < minMychainSdkErrorCode) {
            return ErrorCode.valueOf(errorCode).getErrorDesc();
        } else {
            return ErrorCode.valueOf(errorCode).getErrorDesc();
        }
    }

    private static void initMychainEnv() throws IOException {
        // any user key for sign message
        String userPrivateKeyFile = "user.key";
        userIdentity = Utils.getIdentityByName(account); // 根据实际情况更新'gushui03'为'user.key'对应的账户名(BaaS申请证书时创建的账户名)
        Pkcs8KeyOperator pkcs8KeyOperator = new Pkcs8KeyOperator();
        userKeypair = pkcs8KeyOperator.load(
                IOUtil.inputStreamToByte(AntChainDemo.class.getClassLoader().getResourceAsStream(userPrivateKeyFile)),
                userPassword);

        // use publicKeys by tee
        if (isTeeChain) {
            Keypair keypair = new Pkcs8KeyOperator()
                    .loadPubkey(
                            IOUtil.inputStreamToByte(
                                    AntChainDemo.class.getClassLoader().getResourceAsStream("test_seal_pubkey.pem")));
            byte[] publicKeyDer = keypair.getPubkeyEncoded(); // tee_rsa_public_key.pem 从BaaS下载获取
            publicKeys.add(publicKeyDer);
        }

        env = buildMychainEnv();

        ILogger logger = AbstractLoggerFactory.getInstance(AntChainDemo.class);
        env.setLogger(logger);
    }

    private static ClientEnv buildMychainEnv() throws IOException {
        InetSocketAddress inetSocketAddress = InetSocketAddress.createUnresolved(host, port);
        String keyFilePath = "client.key";
        String certFilePath = "client.crt";
        String trustStoreFilePath = "trustCa";

        // build ssl option
        ISslOption sslOption = new SslBytesOption.Builder()
                .keyBytes(IOUtil.inputStreamToByte(AntChainDemo.class.getClassLoader().getResourceAsStream(keyFilePath)))
                .certBytes(
                        IOUtil.inputStreamToByte(AntChainDemo.class.getClassLoader().getResourceAsStream(certFilePath)))
                .keyPassword(keyPassword)
                .trustStorePassword(trustStorePassword)
                .trustStoreBytes(
                        IOUtil.inputStreamToByte(
                                AntChainDemo.class.getClassLoader().getResourceAsStream(trustStoreFilePath)))
                .build();

        List<InetSocketAddress> socketAddressArrayList = new ArrayList<InetSocketAddress>();
        socketAddressArrayList.add(inetSocketAddress);

        List<SignerBase> signerBaseList = new ArrayList<SignerBase>();
        SignerBase signerBase = MyCrypto.getInstance().createSigner(userKeypair);
        signerBaseList.add(signerBase);
        SignerOption signerOption = new SignerOption();
        signerOption.setSigners(signerBaseList);

        return ClientEnv.build(socketAddressArrayList, sslOption, signerOption);
    }

    private static void signRequest(AbstractTransactionRequest request) {
        // sign request
        long ts = sdk.getNetwork().getSystemTimestamp();
        request.setTxTimeNonce(ts, BaseFixedSizeUnsignedInteger.Fixed64BitUnsignedInteger
                .valueOf(RandomUtil.randomize(ts + request.getTransaction().hashCode())), true);
        request.complete();
        sdk.getConfidentialService().signRequest(env.getSignerOption().getSigners(), request);
    }

    public static void deployContract() throws IOException {
        EVMParameter contractParameters = new EVMParameter();

        // build DeployContractRequest
        DeployContractRequest request = new DeployContractRequest(userIdentity,
                Utils.getIdentityByName(testContractId), contractCode, VMTypeEnum.EVM,
                contractParameters, BigInteger.ZERO);
        TransactionReceiptResponse deployContractResult;
        if (isTeeChain) {
            signRequest(request);

            // generate transaction key
            byte[] transactionKey = ConfidentialUtil.keyGenerate(secretKey,
                    request.getTransaction().getHash().getValue());

            ConfidentialRequest confidentialRequest = new ConfidentialRequest(request, publicKeys, transactionKey);

            deployContractResult = sdk.getConfidentialService().confidentialRequest(confidentialRequest);
        } else {
            deployContractResult = sdk.getContractService().deployContract(request);
        }

        // deploy contract
        if (!deployContractResult.isSuccess()
                || deployContractResult.getTransactionReceipt().getResult() != 0) {
            exit("deployContract",
                    getErrorMsg((int) deployContractResult.getTransactionReceipt().getResult()));
        } else {
            logger.info("deploy contract success.");
        }
    }

    private static void issue() {
        EVMParameter parameters = new EVMParameter("Issue(identity,int256)");
        parameters.addIdentity(userIdentity);
        parameters.addUint(BigInteger.valueOf(100));

        // build CallContractRequest
        CallContractRequest request = new CallContractRequest(userIdentity,
                Utils.getIdentityByName(testContractId), parameters, BigInteger.ZERO, VMTypeEnum.EVM);

        TransactionReceiptResponse callContractResult;
        if (isTeeChain) {
            signRequest(request);

            // generate transaction key
            byte[] transactionKey = ConfidentialUtil.keyGenerate(secretKey,
                    request.getTransaction().getHash().getValue());

            ConfidentialRequest confidentialRequest = new ConfidentialRequest(request, publicKeys, transactionKey);

            callContractResult = sdk.getConfidentialService().confidentialRequest(confidentialRequest);
        } else {
            callContractResult = sdk.getContractService().callContract(request);
        }

        if (!callContractResult.isSuccess() || callContractResult.getTransactionReceipt().getResult() != 0) {
            exit("issue", getErrorMsg((int) callContractResult.getTransactionReceipt().getResult()));
        } else {
            logger.info("issue success.");
        }
    }

    private static void transfer() {
        // contract parameters
        EVMParameter contractParameters = new EVMParameter("Transfer(identity,int256)");
        contractParameters.addIdentity(testAccount1);
        contractParameters.addUint(BigInteger.valueOf(50));

        CallContractRequest request = new CallContractRequest(userIdentity,
                Utils.getIdentityByName(testContractId), contractParameters, BigInteger.ZERO, VMTypeEnum.EVM);

        TransactionReceiptResponse callContractResult;
        if (isTeeChain) {
            signRequest(request);

            // generate transaction key
            byte[] transactionKey = ConfidentialUtil.keyGenerate(secretKey,
                    request.getTransaction().getHash().getValue());

            ConfidentialRequest confidentialRequest = new ConfidentialRequest(request, publicKeys, transactionKey);

            callContractResult = sdk.getConfidentialService().confidentialRequest(confidentialRequest);
        } else {
            callContractResult = sdk.getContractService().callContract(request);
        }

        if (!callContractResult.isSuccess() || callContractResult.getTransactionReceipt().getResult() != 0) {
            exit("transfer", getErrorMsg((int) callContractResult.getTransactionReceipt().getResult()));
        } else {
            logger.info("transfer success.");
        }
    }

    private static BigInteger query(Identity account) {
        // contract parameters
        EVMParameter parameters = new EVMParameter("Query(identity)");
        parameters.addIdentity(account);

        // build call contract request
        CallContractRequest request = new CallContractRequest(userIdentity,
                Utils.getIdentityByName(testContractId), parameters, BigInteger.ZERO, VMTypeEnum.EVM);

        TransactionReceiptResponse callContractResult;
        if (isTeeChain) {
            signRequest(request);

            // generate transaction key
            byte[] transactionKey = ConfidentialUtil.keyGenerate(secretKey,
                    request.getTransaction().getHash().getValue());

            ConfidentialRequest confidentialRequest = new ConfidentialRequest(request, publicKeys, transactionKey);

            callContractResult = sdk.getConfidentialService().confidentialRequest(confidentialRequest);
        } else {
            callContractResult = sdk.getContractService().callContract(request);
        }

        if (!callContractResult.isSuccess() || callContractResult.getTransactionReceipt().getResult() != 0) {
            exit("query", getErrorMsg((int) callContractResult.getTransactionReceipt().getResult()));
        }

        byte[] output = null;
        if (isTeeChain) {
            output = ConfidentialUtil.decrypt(secretKey, callContractResult.getTransactionReceipt().getOutput(),
                    request.getTransaction().getHash().hexStrValue());
        } else {
            output = callContractResult.getTransactionReceipt().getOutput();
        }

        if (output == null) {
            exit("decrypt tee", "decrypt tee output failed");
            return BigInteger.ZERO;
        }

        // decode return values
        EVMOutput contractReturnValues = new EVMOutput(ByteUtils.toHexString(output));
        return contractReturnValues.getUint();
    }

    private static void expect(BigInteger balance, BigInteger expectBalance) {
        if (balance.compareTo(expectBalance) != 0) {
            exit("expect", "the account value is not expected.");
        } else {
            logger.info("check account balance success.");
        }
    }

    private static void initSdk() {
        sdk = new MychainClient();
        boolean initResult = sdk.init(env);
        if (!initResult) {
            exit("initSdk", "sdk init failed.");
        }
    }

    private static String getName(String userName) {
        // contract parameters
//    EVMParameter parameters = new EVMParameter("insert_alone(string,string)");
//    parameters.addString("0");
//    parameters.addString("test");
        System.out.println(Utils.getIdentityByName("scsm01"));
        EVMParameter parameters = new EVMParameter("deny(identity)");
        parameters.addIdentity(Utils.getIdentityByName(userName));

        // build call contract request

        System.out.println(userIdentity);
        CallContractRequest request = new CallContractRequest(userIdentity,
                Utils.getIdentityByName(testContractId), parameters, BigInteger.ZERO, VMTypeEnum.EVM);

        TransactionReceiptResponse callContractResult;
        if (isTeeChain) {
            signRequest(request);

            // generate transaction key
            byte[] transactionKey = ConfidentialUtil.keyGenerate(secretKey,
                    request.getTransaction().getHash().getValue());

            ConfidentialRequest confidentialRequest = new ConfidentialRequest(request, publicKeys, transactionKey);

            callContractResult = sdk.getConfidentialService().confidentialRequest(confidentialRequest);
        } else {
            callContractResult = sdk.getContractService().callContract(request);
        }

        if (!callContractResult.isSuccess() || callContractResult.getTransactionReceipt().getResult() != 0) {
            exit("getName", getErrorMsg((int) callContractResult.getTransactionReceipt().getResult()));
        }

        byte[] output = null;
        if (isTeeChain) {
            output = ConfidentialUtil.decrypt(secretKey, callContractResult.getTransactionReceipt().getOutput(),
                    request.getTransaction().getHash().hexStrValue());
        } else {
            output = callContractResult.getTransactionReceipt().getOutput();
        }

        if (output == null) {
            exit("decrypt tee", "decrypt tee output failed");
            return "";
        }

        // decode return values
        EVMOutput contractReturnValues = new EVMOutput(ByteUtils.toHexString(output));
        return "contractReturnValues.getString()";
    }
    private static String doTx(String contractName, String methodName, String accountName) {
        String parametersName = "";
        switch (methodName){
            case "allow":
                parametersName = "allow(identity)";
                break;
            case "deny":
                parametersName = "deny(identity)";
                break;
        }
        if ("".equals(parametersName)) return "ERROR";

        EVMParameter parameters = new EVMParameter(parametersName);
        parameters.addIdentity(Utils.getIdentityByName(accountName));

        // build call contract request

        CallContractRequest request = new CallContractRequest(userIdentity,
                Utils.getIdentityByName(contractName), parameters, BigInteger.ZERO, VMTypeEnum.EVM);

        TransactionReceiptResponse callContractResult;
        if (isTeeChain) {
            signRequest(request);

            // generate transaction key
            byte[] transactionKey = ConfidentialUtil.keyGenerate(secretKey,
                    request.getTransaction().getHash().getValue());

            ConfidentialRequest confidentialRequest = new ConfidentialRequest(request, publicKeys, transactionKey);

            callContractResult = sdk.getConfidentialService().confidentialRequest(confidentialRequest);
        } else {
            callContractResult = sdk.getContractService().callContract(request);
        }

        if (!callContractResult.isSuccess() || callContractResult.getTransactionReceipt().getResult() != 0) {
            exit("doTx", getErrorMsg((int) callContractResult.getTransactionReceipt().getResult()));
        }

        byte[] output = null;
        if (isTeeChain) {
            output = ConfidentialUtil.decrypt(secretKey, callContractResult.getTransactionReceipt().getOutput(),
                    request.getTransaction().getHash().hexStrValue());
        } else {
            output = callContractResult.getTransactionReceipt().getOutput();
        }

        if (output == null) {
            exit("decrypt tee", "decrypt tee output failed");
            return "";
        }

        // decode return values
        EVMOutput contractReturnValues = new EVMOutput(ByteUtils.toHexString(output));
        return contractReturnValues.getRawOutput();
    }

    public static CallContractResponse callContractDemo() throws IOException {
        initMychainEnv();

        initSdk();

        return callContract();
    }

    public static void main(String[] args) throws Exception {
        // step 1:init mychain env.
        initMychainEnv();
        // step 2: init sdk client
        initSdk();

        // step 3 : deploy a contract using useridentity.
//     deployContract();
        callContract();

        // step 4 issue 100 assets to testAccount1.
        // issue();

        // step 5 : transfer 50 assets from useridentity to testAccount1
        // transfer();

        // step 6 : query testAccount1 whose balance should be 50.
        // BigInteger balance = query(testAccount1);

        // step 7 : compare to expect balance.
        // expect(balance, BigInteger.valueOf(50));


//    if(args.length != 0){
//      String contractName = args[0];
//      String method = args[1];
//      String accountName = args[2];
//      doTx(contractName, method, accountName);
//      sdk.shutDown();
//      return;
//    }
//    String result = getName("damn");

        // step 8 : sdk shut down
        sdk.shutDown();
    }

    public static CallContractResponse callContract() {
        EVMParameter parameters = new EVMParameter("test()");
        CallContractRequest request = new CallContractRequest(Utils.getIdentityByName(account), Utils.getIdentityByName(testContractId), parameters, BigInteger.ZERO, VMTypeEnum.EVM);
        CallContractResponse callContractResponse = sdk.getContractService().callContract(request);
        byte[] output = callContractResponse.getTransactionReceipt().getOutput();
        EVMOutput contractReturnValues = new EVMOutput(ByteUtils.toHexString(output));
        String string = contractReturnValues.getString();
        System.out.println(string);
        return callContractResponse;
    }

    /**
     * 银行开户
     * @param accountId
     */
    public static void setBankAccount(String accountId) throws IOException {
        initMychainEnv();

        initSdk();
        EVMParameter parameters = new EVMParameter("setBankAccount(string)");
        parameters.addString(accountId);
        CallContractRequest request = new CallContractRequest(Utils.getIdentityByName(account), Utils.getIdentityByName(testContractId), parameters, BigInteger.ZERO, VMTypeEnum.EVM);
        CallContractResponse callContractResponse = sdk.getContractService().callContract(request);
        System.out.println("111111111" + callContractResponse.getTransactionReceipt().getResult());
        byte[] output = callContractResponse.getTransactionReceipt().getOutput();
        System.out.println("------------------------------" + new String(output));
    }

    /**
     * 查看银行账户
     * @param accountId
     * @return
     * @throws IOException
     */
    public static Integer getBankAccount(String accountId) throws IOException {
        initMychainEnv();

        initSdk();
        EVMParameter parameters = new EVMParameter("getBankAccount(string)");
        parameters.addString(accountId);
        CallContractRequest request = new CallContractRequest(Utils.getIdentityByName(account), Utils.getIdentityByName(testContractId), parameters, BigInteger.ZERO, VMTypeEnum.EVM);
        CallContractResponse callContractResponse = sdk.getContractService().callContract(request);
        byte[] output = callContractResponse.getTransactionReceipt().getOutput();
        Integer integer = ByteUtils.bytesToInt(output);
        return integer;
    }

    /**
     * 存钱
     * @param accountId
     * @param amount
     * @return
     * @throws IOException
     */
    public static String save(String accountId, Integer amount) throws IOException {
        initMychainEnv();

        initSdk();
        EVMParameter parameters = new EVMParameter("save(string,uint256)");
        parameters.addString(accountId);
        parameters.addUint(BigInteger.valueOf(amount));
        CallContractRequest request = new CallContractRequest(Utils.getIdentityByName(account), Utils.getIdentityByName(testContractId), parameters, BigInteger.ZERO, VMTypeEnum.EVM);
        CallContractResponse callContractResponse = sdk.getContractService().callContract(request);
        return callContractResponse.getTransactionReceipt().getResult() + "";
    }


    public static String withDraw(String accountId, Integer amount) throws IOException {
        initMychainEnv();

        initSdk();
        EVMParameter parameters = new EVMParameter("withDraw(string,uint256)");
        parameters.addString(accountId);
        parameters.addUint(BigInteger.valueOf(amount));
        CallContractRequest request = new CallContractRequest(Utils.getIdentityByName(account), Utils.getIdentityByName(testContractId), parameters, BigInteger.ZERO, VMTypeEnum.EVM);
        CallContractResponse callContractResponse = sdk.getContractService().callContract(request);
        return callContractResponse.getTransactionReceipt().getResult() + "";
    }

    public static String updateContract() throws IOException {
        initMychainEnv();

        initSdk();
        deployContract();
        return "1";
    }

    public static String test() throws IOException {
        initMychainEnv();

        initSdk();
        EVMParameter parameters = new EVMParameter("test1()");
        CallContractRequest request = new CallContractRequest(Utils.getIdentityByName(account), Utils.getIdentityByName(testContractId), parameters, BigInteger.ZERO, VMTypeEnum.EVM);
        CallContractResponse callContractResponse = sdk.getContractService().callContract(request);
        byte[] output = callContractResponse.getTransactionReceipt().getOutput();
        EVMOutput contractReturnValues = new EVMOutput(ByteUtils.toHexString(output));
        String string = contractReturnValues.getString();
        return string;
    }

    public static String testUpdate() {
        return null;
    }
}
